package io.renren.common.sms;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 优讯通短信
 * 
 * @author ypj
 *
 */
public class YxuntongSms {

	//private static String account = "2002557"; // 用户账号(必填)
	//private static String password = "jnhz+123"; // 账号密码，需采用MD5加密(小写)(必填)
	private static String url_submit = "http://new.yxuntong.com/emmpdata/sms/Submit"; // 提交短信接口
	private static String url_deliver = "http://new.yxuntong.com/emmpdata/sms/Deliver"; // 上行接口
	private static String url_report = "http://new.yxuntong.com/emmpdata/sms/Report"; // 状态报告接口
	private static String url_balance = "http://new.yxuntong.com/emmpdata/sms/Balance"; // 金额接口

	/**
	 * 短信下行<br>
	 * 发送一条或则多条内容相同的短信
	 * 
	 * @param phones
	 *            接收手机号码，多个手机号码用英文逗号分隔，最多1000个，不能为空(必填)
	 * @param content
	 *            短信内容，最多350汉字，不能为空(必填)
	 * @param sign
	 *            短信签名，该签名有服务端告知客户端，不可修改。为空时使用默认值(必填)
	 * @param subcode
	 *            扩展子号码，内容可空，暂不支持(非必填)
	 * @param sendtime
	 *            定时下发时间,格式yyyyMMddHHmm,可空(非必填)
	 * @return
	 */
	private static String getSend(String account,String password,String phones, String content, String sign, String subcode, String sendtime) {
		Document doc = DocumentHelper.createDocument();
		doc.setXMLEncoding("UTF-8");
		Element messageEl = doc.addElement("message");
		messageEl.addElement("account").setText(account);
		messageEl.addElement("password").setText(MD5Encode(password));
		messageEl.addElement("phones").setText(phones);
		messageEl.addElement("content").setText(content);
		messageEl.addElement("sign").setText(sign);
		messageEl.addElement("subcode").setText(subcode);
		messageEl.addElement("sendtime").setText(sendtime);
		String message = messageEl.asXML();
		Map<String, String> params = new LinkedHashMap<String, String>();
		params.put("message", message);
		String resp = doPost(url_submit, params);
		System.out.println(resp);
		return resp;
	}

	/**
	 * 短信上行<br>
	 * 获取上行短信。每次调用间隔需大于30秒,每次最多取200条上行短信
	 * 
	 * @return
	 */
	private static String getDeliver() {
		Document doc = DocumentHelper.createDocument();
		doc.setXMLEncoding("UTF-8");
		Element messageEl = doc.addElement("message");
		//messageEl.addElement("account").setText(account);
		//messageEl.addElement("password").setText(MD5Encode(password));
		String message = messageEl.asXML();
		Map<String, String> params = new LinkedHashMap<String, String>();
		params.put("message", message);
		String resp = doPost(url_deliver, params);
		return resp;
	}

	/**
	 * 短信状态报告<br>
	 * 获取下行短信状态报告，每次调用间隔需大于30秒。每次最多取500条
	 * 
	 * @return
	 */
	private static String getReport() {
		Document doc = DocumentHelper.createDocument();
		doc.setXMLEncoding("UTF-8");
		Element messageEl = doc.addElement("message");
		//messageEl.addElement("account").setText(account);
		//messageEl.addElement("password").setText(MD5Encode(password));
		String message = messageEl.asXML();
		Map<String, String> params = new LinkedHashMap<String, String>();
		params.put("message", message);
		String resp = doPost(url_report, params);
		return resp;
	}

	/**
	 * 查询余额<br>
	 * 获取余额，每次调用间隔需大于30秒。
	 * 
	 * @return
	 */
	private static String getBalance() {
		Document doc = DocumentHelper.createDocument();
		doc.setXMLEncoding("UTF-8");
		Element messageEl = doc.addElement("message");
		//messageEl.addElement("account").setText(account);
		//messageEl.addElement("password").setText(MD5Encode(password));
		String message = messageEl.asXML();
		Map<String, String> params = new LinkedHashMap<String, String>();
		params.put("message", message);
		String resp = doPost(url_balance, params);
		return resp;
	}

	/**
	 * 执行一个HTTP POST请求，返回请求响应的HTML
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param params
	 *            请求的查询参数,可以为null
	 * @return 返回请求响应的HTML
	 */
	private static String doPost(String url, Map<String, String> params) {
		String response = null;
		HttpClient client = new HttpClient();
		// 设置超时时间
		HttpConnectionManagerParams httpConnectionManagerParams = client.getHttpConnectionManager().getParams();
		httpConnectionManagerParams.setConnectionTimeout(30 * 1000);
		httpConnectionManagerParams.setSoTimeout(30 * 1000);

		PostMethod postMethod = new PostMethod(url);
		postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");

		// 设置Post数据
		if (!params.isEmpty()) {
			int i = 0;
			NameValuePair[] data = new NameValuePair[params.size()];
			for (Entry<String, String> entry : params.entrySet()) {
				data[i] = new NameValuePair(entry.getKey(), entry.getValue());
				i++;
			}
			postMethod.setRequestBody(data);
		}
		try {
			client.executeMethod(postMethod);
			if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
				BufferedReader reader = new BufferedReader(new InputStreamReader(postMethod.getResponseBodyAsStream()));
				StringBuffer stringBuffer = new StringBuffer();
				String str = null;
				while ((str = reader.readLine()) != null) {
					stringBuffer.append(str);
				}
				response = stringBuffer.toString();
				reader.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			postMethod.releaseConnection();
			client.getHttpConnectionManager().closeIdleConnections(0);
		}
		return response;
	}

	/**
	 * MD5加密函数
	 * 
	 * @param sourceString
	 * @return
	 */
	private static String MD5Encode(String sourceString) {
		String resultString = null;
		try {
			resultString = new String(sourceString);
			MessageDigest md = MessageDigest.getInstance("MD5");
			resultString = byte2hexString(md.digest(resultString.getBytes()));
		} catch (Exception ex) {
		}
		return resultString;
	}

	private static final String byte2hexString(byte[] bytes) {
		StringBuffer bf = new StringBuffer(bytes.length * 2);
		for (int i = 0; i < bytes.length; i++) {
			if ((bytes[i] & 0xff) < 0x10) {
				bf.append("0");
			}
			bf.append(Long.toString(bytes[i] & 0xff, 16));
		}
		return bf.toString();
	}

	/**
	 * 解析XML文档，返回取的根元素
	 * 
	 * @param resp
	 * @return
	 */
	private static Element analyzeXML(String resp) {
		Document doc = null;
		Element rootElt = null;
		try {
			doc = DocumentHelper.parseText(resp); // 将字符串转为XML
			rootElt = doc.getRootElement(); // 获取根节点
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rootElt;
	}

	/**
	 * 发送短信验证吗<br>
	 * 您的手机验证码是123123，请及时验证！非本人操作，请不予理会
	 * 
	 * @param phones
	 *            接收手机号码，多个手机号码用英文逗号分隔，最多1000个，不能为空(必填)
	 * @return 验证码
	 */
	public static String sendCheckCode(String account,String password,String phones) {
		String code = CheckCodeUtils.random() + "";
		String content = "您的手机验证码是" + code + "，有效期15分钟,请及时验证！非本人操作，请不予理会.";
		String resp = getSend(account,password,phones, content, "", "", "");
		Element root = analyzeXML(resp);
		String result = root.elementTextTrim("result");
		if (result.equals("0")) {
			return code;
		} else {
			return null;
		}
	}

	/**
	 * 发送短信
	 * @param phones
	 * @param content
	 */
	public static void sendMsg(String account,String password,String phones,String content) {
		getSend(account,password,phones, content, "", "", "");
	}

	public static void main(String[] args){
		//15527272236
		//YxuntongSms.sendMsg("20013121","jNHZ10+","15953295779","尊敬的谢威，您2019宁波机床模具展的Vip电子门票链接为 preg.jinnoc.com/t/16708 ,请直接现场刷闸机入场.");
		//YxuntongSms.sendMsg("2002557","jnhz+123","15953295779","王虎成您好，您的朋友谢威邀请您一起报名2019宁波机床模具展预登记观众. 体验链接：t.cn/AipZ1OQx 回T退");
		//YxuntongSms.sendMsg("20013121","jNHZ10+","15953295779","王虎成您好，您的朋友谢威邀请您一起报名2019宁波机床模具展预登记观众. 体验链接：t.cn/AipZ1OQx 回T退");
		//YxuntongSms.sendMsg("2001283","HZ1104","15527272236","尊敬的谢威,您2019宁波机床模具展的预登记电子门票链接 preg.jinnoc.com/t/16708 回T退");
		//YxuntongSms.sendMsg("2001283","HZ1104","15527272236","谢威您好，您的朋友王虎成邀请您注册为xxx预登记观众,体验链接：preg.jinnoc.com/t/16708 回T退");
		YxuntongSms.sendCheckCode("2002557","jnhz+123","15953295779");
	}
}
